function TITTInvoker(tokens, serviceID) {

	var id = serviceID;
	if(id == null)
		id = "titt";
	var key = KeyFactory.createKey(tokens);
	var ef = IOFactory.createEncodingFacade();

	this.dynCall = function(methodName, args, callback) {
		var targs = new Array();

		for(var id in args) {
			targs[id] = new TypedObject(new TypeFromObject(args[id]), args[id]);
		}

		this.call(methodName, targs, function(ret) { callback(ret.getObject()); });
	}
	
	this.advCall = function(methodName, retType, args, callback) {
		this.call(methodName, args, callback);
	}
	
	this.call = function(methodName, args, callback) {
		try {
			var ts = IOFactory.createTITTSocket();
	
			var method = TITTValues.GET;
			if(args.length > 0) method = TITTValues.POST;

			var m = new MethodHeadInit(methodName, [], [], new RequestHeadInit(method, key.asKeyString(), HeadFactory.createHead1([new Header("Accept", id)])));

			if(args.length > 0) {
				var pw = new POSTWriter(ts, ef, m);
				pw.writeValues(args, handleResponse);
			}
			else {
				ts.getHeadWriter().writeHead(m);
				ts.getOutputStream().flush(handleResponse);
			}		
		}
		catch(err) {
			callback(null);
		}
		function handleResponse() {
			//TODO: async error handling here ##return null in callback?
			try {
				var responseHead = new ResponseHead(ts.getHeadReader().readHead());
				var reader = new ResponseReader(ts, ef, responseHead);
				callback(reader.readValues()[0]);
				delete responseHead; delete reader;
			}
			catch(err) {
				callback(null);
			}
			ts.close();
			delete ts; delete method; delete m; delete pw;
		}
		
	}
	
}
